package com.platform.common.cache.redis.serializer;

import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class GenericMsgPackRedisSerializer implements RedisSerializer<Object> {

	private final ObjectMapper mapper;

	public GenericMsgPackRedisSerializer() {
		mapper = MsgPackSerializerHelper.OBJECT_MAPPER;
	}

	@Override
	public byte[] serialize(Object source) throws SerializationException {
		if (source == null) {
			return MsgPackSerializerHelper.EMPTY_ARRAY;
		}
		try {
			return mapper.writeValueAsBytes(source);
		} catch (JsonProcessingException e) {
			throw new SerializationException("Could not write JSON use msgpack: " + e.getMessage(), e);
		}
	}

	@Override
	public Object deserialize(byte[] source) throws SerializationException {
		return deserialize(source, Object.class);
	}

	/**
	 * @param source can be {@literal null}.
	 * @param type must not be {@literal null}.
	 * @return {@literal null} for empty source.
	 * @throws SerializationException
	 */
	public <T> T deserialize(byte[] source, Class<T> type) throws SerializationException {
		Assert.notNull(type, "Deserialization type must not be null! Pleaes provide Object.class to make use of Jackson2 default typing.");
		if ((source == null || source.length == 0)) {
			return null;
		}
		try {
			return mapper.readValue(source, type);
		} catch (Exception ex) {
			throw new SerializationException("Could not read JSON: " + ex.getMessage(), ex);
		}
	}
}
